package com.cmcc.passenger.ui.places

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.cmcc.shared.adapter.SingleItemAdapter
import com.cmcc.shared.adapter.SingleItemBinder
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.cmcc.passenger.R
import com.cmcc.passenger.config.PassPath
import com.cmcc.passenger.config.PassPath.DIRECTION_SEARCH
import com.cmcc.passenger.data.entity.Coordinates
import com.cmcc.passenger.data.entity.FavoriteAddress
import com.cmcc.passenger.data.entity.PlaceAutoComplete
import com.cmcc.passenger.databinding.ActivityPlaceSearchBinding
import com.cmcc.passenger.databinding.ListItemSearchResultBinding
import com.cmcc.passenger.ui.base.BasicActivity
import com.cmcc.passenger.ui.fragment.AppAlertDialog
import com.cmcc.passenger.ui.fragment.AppProgressDialog
import com.cmcc.passenger.ui.profile.AddressBookActivity
import com.cmcc.shared.utils.L
import com.cmcc.shared.utils.clickWithTrigger
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.AutocompleteSessionToken
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.api.net.FetchPlaceRequest
import com.google.android.libraries.places.api.net.FindAutocompletePredictionsRequest
import com.google.android.libraries.places.api.net.PlacesClient

@Route(path = DIRECTION_SEARCH)
class PlaceSearchActivity : BasicActivity(), TextWatcher {
    private lateinit var binding: ActivityPlaceSearchBinding

    private lateinit var placesClient: PlacesClient

    private var adapter: SingleItemAdapter? = null

    private lateinit var viewModel: PlaceSearchViewModel

    private var isFromAddressBook = false
    private var isHKDistrict = true

    private var progressDialog: AppProgressDialog? = null

    private var requestCode = -1
    private val homeAddress: MutableList<PlaceAutoComplete> = mutableListOf()
    private val companyAddress: MutableList<PlaceAutoComplete> = mutableListOf()
    private val favoriteAddress: MutableList<PlaceAutoComplete> = mutableListOf()

    override fun initialize(savedInstanceState: Bundle?) {

        if (!Places.isInitialized()) {
            Places.initialize(applicationContext, getString(R.string.google_maps_key))
        }
        // Create a new Places client instance.
        placesClient = Places.createClient(this)

        isFromAddressBook = intent.getBooleanExtra("address_book", false)
        requestCode = intent.getIntExtra("request_code", -1)

        viewModel = ViewModelProviders.of(this).get(PlaceSearchViewModel::class.java)
        progressDialog?.show()
    }


    override fun initView(savedInstanceState: Bundle?) {
        progressDialog = AppProgressDialog(this)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_place_search)
        binding.viewModel = viewModel
        binding.location.addTextChangedListener(this)
        setSupportActionBar(binding.toolbar.toolbar)
        supportActionBar!!.title = ""
        binding.toolbar.title.text = getString(R.string.place_search)
        binding.toolbar.toolbar.setNavigationOnClickListener { finish() }

        var hint = getString(R.string.where_are_you_go)
        when (requestCode) {
            1 ->
                hint = getString(R.string.plz_input_home_address)
            2 ->
                hint = getString(R.string.plz_input_company_address)
            3 ->
                hint = getString(R.string.plz_input_common_address)
            4 ->
                hint = getString(R.string.plz_input_start_address)
            5 ->
                hint = getString(R.string.plz_input_end_address)
        }
        binding.location.hint = hint

        val viewBinder = PlaceSearchViewBinder()

        viewBinder.setOnFavoriteClickListener(object :
            OnItemClickListener<ListItemSearchResultBinding, PlaceAutoComplete> {
            override fun onItemClick(view: ListItemSearchResultBinding, model: PlaceAutoComplete) {

                val placeId = model.placeId
                // Specify the fields to return.
                val placeFields = listOf(Place.Field.ID, Place.Field.LAT_LNG)

                // Construct a request object, passing the place ID and fields array.
                val request = FetchPlaceRequest.newInstance(placeId, placeFields)
                progressDialog?.show()
                placesClient.fetchPlace(request).addOnSuccessListener { result ->
                    val place = result.place
                    val coordinates = Coordinates(
                        place.latLng?.latitude,
                        place.latLng?.longitude
                    )

                    if (!isFromAddressBook) {
                        progressDialog?.dismiss()
                        val intent = Intent()
                        intent.putExtra("direction", model.firstAddress)
                        intent.putExtra("placeId", model.placeId)
                        setResult(Activity.RESULT_OK, intent)
                        finish()
                    } else {
                        progressDialog?.dismiss()
                        addAddress(model, coordinates)
                    }
                }
            }
        })

        viewBinder.setOnItemClickListener(object :
            OnItemClickListener<ListItemSearchResultBinding, PlaceAutoComplete> {
            override fun onItemClick(view: ListItemSearchResultBinding, model: PlaceAutoComplete) {

                val placeId = model.placeId
                // Specify the fields to return.
                val placeFields = listOf(Place.Field.ID, Place.Field.LAT_LNG)

                // Construct a request object, passing the place ID and fields array.
                val request = FetchPlaceRequest.newInstance(placeId, placeFields)
                progressDialog?.show()
                placesClient.fetchPlace(request).addOnSuccessListener { result ->
                    val place = result.place
                    val coordinates = Coordinates(
                        place.latLng?.latitude,
                        place.latLng?.longitude
                    )

                    if (!isFromAddressBook) {
                        progressDialog?.dismiss()
                        val intent = Intent()
                        intent.putExtra("direction", model.firstAddress)
                        intent.putExtra("placeId", model.placeId)
                        setResult(Activity.RESULT_OK, intent)
                        finish()
                    } else {
                        progressDialog?.dismiss()
                        addAddress(model, coordinates)
                    }
                }
            }
        })
        adapter = SingleItemAdapter(viewBinder as SingleItemBinder)
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = adapter
        binding.locationSort.container.visibility =
            if (isFromAddressBook) View.GONE else View.VISIBLE
    }

    /**
     * 添加常用地址
     */
    private fun addAddress(model: PlaceAutoComplete, coordinates: Coordinates) {
        if (!isAdded(model.placeId)) {
            val address = FavoriteAddress(
                coordinates,
                null,
                model.secondAddress + " " + model.firstAddress,
                model.placeId,
                getAddressType(requestCode)
            )
            viewModel.addAddress(address)
                .observe(this@PlaceSearchActivity, Observer {
                    val intent = Intent()
                    intent.putExtra("direction", model.firstAddress)
                    intent.putExtra("placeId", model.placeId)
                    setResult(Activity.RESULT_OK, intent)
                    finish()
                })
        } else {
            AppAlertDialog(this@PlaceSearchActivity).setContent(getString(R.string.address_is_here))
                .setNavigation("", null, false)
                .setPositive(getString(R.string.make_sure), null).show()
        }
    }

    /**
     * 根据request code 获取类型，1表示家里地址，2表示公司地址，3表示常用地址
     */
    private fun getAddressType(requestCode: Int): Int {
        return when (requestCode) {
            AddressBookActivity.REQUEST_ADD_HOME_CODE -> 1
            AddressBookActivity.REQUEST_ADD_COMPANY_CODE -> 2
            AddressBookActivity.REQUEST_ADD_FAVORITY_CODE -> 3
            else -> 3
        }
    }

    override fun onResume() {
        super.onResume()

        viewModel.getAddress()
    }

    override fun initEvent(savedInstanceState: Bundle?) {

        binding.tvDistrict.clickWithTrigger {
            if (isHKDistrict) {
                binding.tvDistrict.text = getString(R.string.mainland)
            } else {
                binding.tvDistrict.text = getString(R.string.hk)
            }
            isHKDistrict = !isHKDistrict
        }
    }

    override fun initObserver(savedInstanceState: Bundle?) {
        viewModel.address.observe(this, Observer { addressBook ->
            progressDialog?.dismiss()
            if(null != addressBook.homes){
                addressBook.homes.forEach { predicted ->
                    val index = predicted.name?.indexOf(" ") ?: 0

                    var firstAddress: String
                    var secondAddress: String
                    if (index > 0) {
                        secondAddress = predicted.name?.substring(0, index) ?: ""
                        firstAddress =
                            predicted.name?.substring(index, predicted.name?.length ?: 0)?.trim() ?: ""
                    } else {
                        secondAddress = predicted.name ?: ""
                        firstAddress = predicted.name ?: ""
                    }

                    homeAddress.add(
                        PlaceAutoComplete(
                            null,
                            predicted.placeId ?: "",
                            null,
                            firstAddress,
                            secondAddress,
                            predicted.name ?: "",
                            true
                        )
                    )
                    binding.locationSort.home.text = firstAddress
                }
            }

            if(null != addressBook.companys){
                addressBook.companys.forEach { predicted ->
                    val index = predicted.name?.indexOf(" ") ?: 0

                    var firstAddress: String
                    var secondAddress : String
                    if (index > 0) {
                        secondAddress = predicted.name?.substring(0, index) ?: ""
                        firstAddress =
                            predicted.name?.substring(index, predicted.name?.length ?: 0)?.trim() ?: ""
                    } else {
                        secondAddress = predicted.name ?: ""
                        firstAddress = predicted.name ?: ""
                    }
                    companyAddress.add(
                        PlaceAutoComplete(
                            null,
                            predicted.placeId ?: "",
                            null,
                            firstAddress,
                            secondAddress,
                            predicted.name ?: "",
                            true
                        )
                    )
                    binding.locationSort.company.text = firstAddress
                }
            }

            if(null != addressBook.commons) {
                addressBook.commons.forEach { predicted ->
                    val index = predicted.name?.indexOf(" ") ?: 0

                    var firstAddress: String
                    var secondAddress: String
                    if (index > 0) {
                        secondAddress = predicted.name?.substring(0, index) ?: ""
                        firstAddress =
                            predicted.name?.substring(index, predicted.name?.length ?: 0)?.trim()
                                ?: ""
                    } else {
                        secondAddress = predicted.name ?: ""
                        firstAddress = predicted.name ?: ""
                    }
                    favoriteAddress.add(
                        PlaceAutoComplete(
                            null,
                            predicted.placeId ?: "",
                            null,
                            firstAddress,
                            secondAddress,
                            predicted.name ?: "",
                            true
                        )
                    )
                }
            }

        })
        viewModel.companySelector().observe(this, Observer {
            binding.locationSort.tvHome.isSelected = false
            binding.locationSort.tvCompany.isSelected = true
            binding.locationSort.tvFavorite.isSelected = false
//            adapter?.submitList(companyAddress as List<PlaceAutoComplete>)

            if (companyAddress.size == 0) {
                ARouter.getInstance().build(PassPath.FAVORITE_ADDRESS).navigation()
            } else {
                setResultForActivity(companyAddress[0])
            }
        })

        viewModel.homeSelector().observe(this, Observer {
            binding.locationSort.tvHome.isSelected = true
            binding.locationSort.tvCompany.isSelected = false
            binding.locationSort.tvFavorite.isSelected = false
//            adapter?.submitList(homeAddress as List<PlaceAutoComplete>)

            if (homeAddress.size == 0) {
                ARouter.getInstance().build(PassPath.FAVORITE_ADDRESS).navigation()
            } else {
                setResultForActivity(homeAddress[0])
            }
        })

        viewModel.favoriteSelector().observe(this, Observer {
            binding.locationSort.tvHome.isSelected = false
            binding.locationSort.tvCompany.isSelected = false
            binding.locationSort.tvFavorite.isSelected = true
            adapter?.submitList(favoriteAddress as List<PlaceAutoComplete>)
        })
    }

    private fun setResultForActivity(model: PlaceAutoComplete) {
//        val placeId = model.placeId
//        // Specify the fields to return.
//        val placeFields = listOf(Place.Field.ID, Place.Field.LAT_LNG)
//
//        // Construct a request object, passing the place ID and fields array.
//        val request = FetchPlaceRequest.newInstance(placeId, placeFields)
//        progressDialog?.show()
//        placesClient.fetchPlace(request).addOnSuccessListener { result ->
//            val place = result.place
//            val coordinates = Coordinates(
//                place.latLng?.latitude,
//                place.latLng?.longitude
//            )
//
//            progressDialog?.dismiss()
//            val intent = Intent()
//            intent.putExtra("direction", model.firstAddress)
//            intent.putExtra("placeId", model.placeId)
//            setResult(Activity.RESULT_OK, intent)
//            finish()
//        }

        val intent = Intent()
        intent.putExtra("direction", model.firstAddress)
        intent.putExtra("placeId", model.placeId)
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {

    }

    override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {

    }

    override fun afterTextChanged(editable: Editable) {

        val token = AutocompleteSessionToken.newInstance()
        // Create a RectangularBounds object.
//        val bounds = RectangularBounds.newInstance(
//            LatLng(-33.880490, 151.184363), //dummy lat/lng
//            LatLng(-33.858754, 151.229596)
//        )
        // Use the builder to create a FindAutocompletePredictionsRequest.
        val request = FindAutocompletePredictionsRequest.builder()
            // Call either setLocationBias() OR setLocationRestriction().
//            .setLocationBias(bounds)
            //.setLocationRestriction(bounds)

            .setCountry(if (isHKDistrict) "hk" else "cn")

//            .setTypeFilter(TypeFilter.ESTABLISHMENT)
            .setSessionToken(token)
            .setQuery(editable.toString())
            .build()


        placesClient.findAutocompletePredictions(request).addOnSuccessListener { response ->
            run {
                val places = mutableListOf<PlaceAutoComplete>()

                for (prediction in response.autocompletePredictions) {
                    places.add(
                        PlaceAutoComplete(
                            null,
                            prediction.placeId,
                            prediction.placeTypes,
                            prediction.getPrimaryText(null).toString(),
                            prediction.getSecondaryText(null).toString(),
                            prediction.getFullText(null).toString(),
                            isAdded(prediction.placeId)
                        )
                    )
                }
                adapter?.submitList(places as List<PlaceAutoComplete>)
            }
        }.addOnFailureListener {
            L.d("addOnFailureListener")
        }

    }

    /**
     * 判断地址是否已经收藏
     */
    private fun isAdded(placeId: String): Boolean {
        var contain = false
        homeAddress.forEach { predicted ->
            contain = (predicted.placeId == placeId)
            if (contain) return contain
        }
        companyAddress.forEach { predicted ->
            contain = predicted.placeId == placeId
            if (contain) return contain
        }
        favoriteAddress.forEach { predicted ->
            contain = predicted.placeId == placeId
            if (contain) return contain
        }
        return contain
    }
}
